<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html> <head> <title> HaXml: Haskell and XML </title> </head>

<body bgcolor='#ffffff'>

<center>
<h2>XmlContent</h2>
</center>
<hr>

<p>
<b>Text.XML.HaXml.XmlContent</b> is a library/class for translating
Haskell data from any program into a valid XML document (and back
again).  In principle, it gives an alternative to the standard Read and
Show classes, allowing you to use fully typed data in Haskell rather
than the generic XML tree representation.

<p>
<b>Usage 1.</b>
It works rather like the existing <em>Read</em> and <em>Show</em>
classes: you must create an instance of the <em>XmlContent</em>
class for every datatype you wish to use for I/O.  However, because
this class is not a standard one, no Haskell compilers support
the <tt>deriving</tt> clause for it yet.  Fear not!  There is a
pre-processor tool called
<a href="http://repetae.net/~john/computer/haskell/DrIFT/"><b>DrIFT</b></a>
which derives class instances automatically.  We have extended
DrIFT's ruleset to include the <em>XmlContent</em> class.

<p>
(Please note that DrIFT is sometimes a bit fragile when parsing Haskell
sources - it occasionally fails to recognise the <em>derive</em>
command.  We have found a workaround: isolate just the <tt>data</tt>
type declarations that are of interest, and run DrIFT on them
separately.)  The syntax required is like this example:
<pre>
  data MyType a = A a | B String deriving (Eq, Show)
      {-! derive : XmlContent !-}	-- this line is for DrIFT
</pre>

<p>
<b>Usage 2.</b>
Alternatively, you may start by having XML documents with a standard DTD
defined elsewhere, e.g. SVG, SMIL, MathML etc.  You can convert the DTD
into an isomorphic collection of Haskell datatypes, including all the
requisite instances of <em>XmlContent</em>, with the tool
<em>DtdToHaskell</em> included in HaXml.

<p>
<b>Usage 3.</b>
Finally, you may have a document type definition expressed in XML Schema
rather than a DTD.  Use the <em>XsdToHaskell</em> tool in this case, to
convert the Schema into an isomorphic collection of Haskell datatypes,
including all the requisite instances of <em>XmlContent</em>.


<p>
<b>API</b>
To read and write Haskell data values as XML files, you
have a choice of function pairs:  <tt>toXML/fromXML</tt>
convert between typed Haskell values and the generic internal
XML representation; <tt>showXml/readXml</tt> convert to/from
Strings; <tt>fWriteXml/fReadXml</tt> convert to/from named files;
<tt>hPutXml/hGetXml</tt> convert to/from file Handles.

<pre>
    toXml     :: XmlContent a =&gt; Bool -&gt; a  -&gt; Document ()
    fromXml   :: XmlContent a =&gt; Document Posn -&gt; Either String a

    readXml   :: XmlContent a =&gt; String        -&gt; Either String a
    showXml   :: XmlContent a =&gt; Bool -&gt; a  -&gt; String

    fReadXml  :: XmlContent a =&gt; FilePath -&gt; IO a
    fWriteXml :: XmlContent a =&gt; FilePath -&gt; a -&gt; IO ()

    hGetXml   :: XmlContent a =&gt; Handle   -&gt; IO a
    hPutXml   :: XmlContent a =&gt; Handle   -&gt; Bool -&gt; a -&gt; IO ()
</pre>

Because parsing the document might fail, some of these functions return
an Either String, where the string contains an error message.  Boolean
arguments to output-writing functions indicate whether or not to include
a DTD in the output.

<p>
Particularly when you read from XML, you may need to resolve the
overloading of the result value in one of the usual ways (e.g. by
implicit context at point of use, by explicit type signatures on values,
use value as an argument to a function with an explicit signature, use
<tt>`asTypeOf`</tt>, etc.)

<hr>

</body>
</html>
